package com.sdlh.demo.functional;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;

public class FunctionalDemo {
    public static void main(String[] args) {
        testFunctional();
//        testLambdaVariableScope();
//        testHighOrderFuncArray();
        //java实现类似于python的函数装饰器
        Hello hello = new Hello() {
            @Override
            public void hello(String person) {
                System.out.println("Decorate begin");
                super.hello(person);
                System.out.println("Decorate end");
            }
        };
        hello.hello("zak");
    }

    /**
     * 通过闭包将局部变量变成全局变量，延长了变量的作用域，有造成内存泄漏的风险。
     * 以lambda匿名函数作为返回值的函数newAdder是一个高阶函数
     *
     * @return
     */
    private static IAdder newAdder() {
        AtomicInteger a = new AtomicInteger(0);
        return () -> a.incrementAndGet();
    }

    private static void testLambdaVariableScope() {
        IAdder adder = newAdder();
        for (int i = 0; i < 100; i++) {
            if (i % 2 == 0) {
                System.out.println("a=" + adder.add());
            }
        }
    }

    private static void testFunctional() {
        Consumer f = System.out::println;
        Consumer f1 = n -> System.out.println(n + "-F1");
        Consumer f2 = n -> System.out.println(n + "-F2");
        //执行完F后再执行F2的Accept方法
        f.andThen(f1).andThen(f2).accept("test");
    }

    private static void testHighOrderFuncArray() {
        Function<Integer, Integer> doubleFunc = o -> 2 * o;
        Function<Integer, Integer> tripleFunc = o -> 3 * o;
        Function<Integer, Integer> squareFunc = o -> o * o;

        Function[] funcs = {doubleFunc, tripleFunc, squareFunc};
        Stream.of(funcs)
              .map(func -> func.apply(4))
              .forEach(System.out::println);
    }

}
